//
//  RHBleCmdManager.m
//  RuiHeAppApp
//
//  Created by bill on 2024/4/27.
//

#import "RHBleCmdManager.h"
#import "RHBleCmdData.h"
#import "CBLEDataParse.h"
#import "CBLECenterMnger.h"
#import "AppDelegate.h"
#import "RHCustomTimer.h"
#import "JCDataConvert.h"

#define CMD_TIME_OUT     3  //指令回复超时时间
#define CMD_RESEND_COUNT 3  //指令回复超时重发次数

@interface RHBleCmdManager()
//要发送的指令
@property (nonatomic,strong) NSMutableArray *cmdArray;
//当前发送指令的索引
@property (nonatomic ,assign) NSInteger cmdIndex;
//发送命令后没有回复超时定时器
@property (nonatomic ,strong) NSTimer *cmdTimeOutTimer;
//超时时间
@property (nonatomic ,assign) NSInteger timeCount;
//指令回复超时重发次数
@property (nonatomic ,assign) NSInteger resendCount;
//发送读指令还是写指令
@property (nonatomic ,copy) void (^cmdBlock)(void);

@property (nonatomic ,strong) NSTimer *heartTimer;

@property (nonatomic ,assign) NSInteger heartCount;
@end

@implementation RHBleCmdManager
-(NSMutableArray *)cmdArray
{
    if(!_cmdArray){
        _cmdArray = [NSMutableArray array];
    }
    return _cmdArray;
}
+ (RHBleCmdManager *)shareMnger{
    
    static dispatch_once_t pred = 0;
    static RHBleCmdManager   *_bleCmdMnger = nil;
    dispatch_once(&pred, ^{
        _bleCmdMnger = [[self alloc] init];

    });
    return _bleCmdMnger;
}

-(instancetype)init{
    if ( self = [super init] ){
        ADD_MESSAGE(BLEMSG_PHERAL_SENDMSG_ACK, receiveDeviceInfo:);
        _resendCount = 0;
    }
    return self;
}
-(void)setCmdIndex:(NSInteger)cmdIndex
{
    _cmdIndex = cmdIndex;
    NSLog(@"----->cmdIndex:%ld",cmdIndex);
}

//心跳包指令
-(void)sendHeartCommand:(RHLocalSettingModel*)heartModel
{
    NSData *data =  [RHBleCmdData buildSingleReadCmdWithSettingModel:heartModel settingType:[heartModel.cmdType integerValue]];
    //将前两个字节换成FFFF
    NSData *subData = [data subdataWithRange:NSMakeRange(2, data.length - 2)];
    NSData *tag_data = [JCDataConvert hexToBytes:@"FFFF"];
    NSMutableData *heartData = [NSMutableData dataWithData:tag_data];
    [heartData appendData:subData];
    [[CBLECenterMnger shareMnger] wristReadData:heartData];
    NSLog(@"---->发送心跳包指令");
}

-(void)readDeviceInfoWithCmdModel:(RHLocalSettingModel*)cmdModel
{
    NSData *data =  [RHBleCmdData buildSingleReadCmdWithSettingModel:cmdModel settingType:[cmdModel.cmdType integerValue]];
    [[CBLECenterMnger shareMnger] wristReadData:data];
    
}


//读设备信息
-(void)readDeviceInfoFromBle:(NSArray*)cmdArray
{
    self.resendCount = 0;
    if(cmdArray.count == 0){
        [ProgressHUDManage hideTips];
        [self.cmdTimeOutTimer invalidate];
        self.cmdTimeOutTimer = nil;
        return;
    }
    kWeakSelf;
    
    self.cmdArray = [NSMutableArray arrayWithArray:cmdArray];
    self.cmdBlock = ^{
        [weakSelf sendReadCmd];
    };
    self.cmdIndex = 0;
    self.cmdBlock();
}

//写设备信息
-(void)writeDeviceInfoFromBle:(NSArray*)cmdArray
{
    self.resendCount = 0;
    if(cmdArray.count == 0){
        [ProgressHUDManage hideTips];
        [self.cmdTimeOutTimer invalidate];
        self.cmdTimeOutTimer = nil;
        return;
    }
    
    kWeakSelf;
    
    self.cmdArray = [NSMutableArray arrayWithArray:cmdArray];
    self.cmdBlock = ^{
        [weakSelf sendWriteCmd];
    };
    self.cmdIndex = 0;
    self.cmdBlock();
}


//发送读取指令
-(void)sendReadCmd
{
    if([CBLECenterMnger shareMnger].curPheral == nil){
        [ProgressHUDManage showInfo: @"蓝牙已断开!".rh_localized];
        [self.cmdTimeOutTimer invalidate];
        self.cmdTimeOutTimer = nil;
        return;
    }
    if(self.cmdIndex >= self.cmdArray.count)return;
    
    RHLocalSettingModel *settingModel = self.cmdArray[self.cmdIndex];
    NSLog(@"---->发送第%ld条读取指令:%@",self.cmdIndex,settingModel.field);
    if([ProgressHUDManage shareObject].showLoadingTips){
        [ProgressHUDManage showLoading: [NSString stringWithFormat:@"%@(%ld/%ld)",@"读取数据".rh_localized,self.cmdIndex+1,self.cmdArray.count]];
    }
    
    NSData *data =  [RHBleCmdData buildSingleReadCmdWithSettingModel:settingModel settingType:[settingModel.cmdType integerValue]];
    [[CBLECenterMnger shareMnger] wristReadData:data];
    self.timeCount = 0;
    //开始计时,5秒内没收到应答就继续发送下一条指令
    [self timeOutAction];
}

//发送写指令
-(void)sendWriteCmd
{
    if(self.cmdArray.count == 0){
        [ProgressHUDManage hideTips];
        [MBProgressHUD dismiss];
        return;
    }
    
    if([CBLECenterMnger shareMnger].curPheral == nil){
        [ProgressHUDManage showInfo:@"蓝牙已断开!".rh_localized];
        [self.cmdTimeOutTimer invalidate];
        self.cmdTimeOutTimer = nil;
        return;
    }
    
    RHLocalSettingModel *settingModel = self.cmdArray[self.cmdIndex];
    NSLog(@"---->发送第%ld条设置指令:%@",self.cmdIndex+1,settingModel.field);
    if([ProgressHUDManage shareObject].showLoadingTips){
        [ProgressHUDManage showLoading: [NSString stringWithFormat:@"%@(%ld/%ld)",@"设置参数".rh_localized,self.cmdIndex+1,self.cmdArray.count]];
    }
   
    NSData *data =  [RHBleCmdData buildSingleSetCmdWithSettingModel:settingModel settingType:[settingModel.cmdType integerValue]];
    [[CBLECenterMnger shareMnger] wristWriteData:data];
    //如果发送的是配网指令,发完结束命令后,设备会自动断开,要取消自动重连
    if ([settingModel.field containsString:@"NET:"]) {
        [CBLECenterMnger shareMnger].isManualDisconnect = YES;
    }
    
    self.timeCount = 0;
    //开始计时,5秒内没收到应答就继续发送下一条指令
    [self timeOutAction];
}


-(void)timeOutAction
{
    [self.cmdTimeOutTimer invalidate];
    self.cmdTimeOutTimer = nil;
    self.timeCount = 0;
    self.cmdTimeOutTimer = [RHCustomTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeCounting) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop]addTimer:self.cmdTimeOutTimer forMode:NSRunLoopCommonModes];
}

-(void)timeCounting
{
    if(self.timeCount >= CMD_TIME_OUT){
        if(self.resendCount >= CMD_RESEND_COUNT){
            [ProgressHUDManage showInfo: @"响应超时".rh_localized];
            [self.cmdTimeOutTimer invalidate];
            self.cmdTimeOutTimer = nil;
            [self.cmdArray removeAllObjects];
            return;
        }
//        //发送下一条指令
//        self.cmdIndex ++;
//        if(self.cmdIndex >= self.cmdArray.count){
//            [self.hud hideAnimated:YES];
//            [MBProgressHUD dismiss];
//            [self.cmdTimeOutTimer invalidate];
//            self.cmdTimeOutTimer = nil;
//            POST_MESSAGE(BLEMSG_PHERAL_SENDMSG_FINISH);
//            return;
//        }
        self.resendCount++;
        NSLog(@"----->超时重发%ld",self.resendCount);
//        [MBProgressHUD showtext:[NSString stringWithFormat:@"第%ld次超时重发",self.resendCount]];
        self.cmdBlock();
        return;
    }
    self.timeCount++;
    NSLog(@"---->计时:%ld",self.timeCount);
}

-(void)cancelTimeOutAction
{
    [self.cmdTimeOutTimer invalidate];
    self.cmdTimeOutTimer = nil;
    self.timeCount = 0;
}

-(void)removeAllCommand
{
    [self cancelTimeOutAction];
    [self.cmdArray removeAllObjects];
    self.cmdIndex = 0;
}
#pragma mark --------------- 收到设备信息 ---------------
-(void)receiveDeviceInfo:(NSNotification*)no
{
    
    NSDictionary *dic = [no object];
    NSLog(@"----->收到设备数据:%@",dic);
    if(dic.allKeys.count==0)return;
    //如果返回错误码(
    if(dic[@"unknowKey"]){
        [ProgressHUDManage showInfo: dic[@"unknowKey"]];
        [self.cmdTimeOutTimer invalidate];//停止超时计时
        self.cmdTimeOutTimer = nil;
        [self startHeartTimer];
        return;
    }
    self.resendCount = 0;
    
    //消息是读还是写回复
    int answerType = [dic[CMD_CODE] intValue];
    int cmdType    = [dic[CMD_TYPE] intValue];
    
    //配网指令返回字符串,其他的返回data便于不同的解析
//    if ([dic[CMD_ADDRESS_VALUE] isKindOfClass:[NSData class]]) {
        //    NSData *valueData = dic[CMD_ADDRESS_VALUE];
        //
        //    int value = [JCDataConvert dataToInt:valueData];
            
            //模块失联,停止下发命令
        //    if(value == 0x06){
        //        [self.cmdTimeOutTimer invalidate];
        //        self.cmdTimeOutTimer = nil;
        //        [self.cmdArray removeAllObjects];//不能移除,心跳包
        //        NSLog(@"------>模块失联,停止发送命令");
        //        return;
        //    }
//    }
    if((self.cmdIndex == self.cmdArray.count-1) && (self.cmdArray.count>0)){
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [ProgressHUDManage hideTips];
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                POST_MESSAGE(BLEMSG_PHERAL_SENDMSG_FINISH);
            });
        });
    }
    
    //收到正常解析的回复
    if(answerType == 0x03||
       answerType == 0x10||
       answerType > 128||
       cmdType    == LocalSettingType_NetWorkConfig){
        //读,写回复
        
        //不管成功失败都发送下一条读数据(有些页面包含多个端点的数据)
        if(self.cmdIndex < self.cmdArray.count-1){
            NSLog(@"---->下发下一条数据:%ld",self.cmdIndex+1);
            self.cmdIndex ++ ;
            self.cmdBlock();
        }else{
            NSLog(@"----命令下发完毕 ");
//            [ProgressHUDManage hideTips];
            [self.cmdTimeOutTimer invalidate];
            self.cmdTimeOutTimer = nil;
            [self startHeartTimer];
            
        }
    }
    
   
}



-(void)cancelWork:(UIButton*)button
{
    [self.cmdTimeOutTimer invalidate];
    self.cmdTimeOutTimer = nil;
    [self removeAllCommand];
    self.cmdIndex = 0;
}

-(void)startHeartTimer
{
    self.heartCount = 0;
    if (self.heartTimer == nil) {
        self.heartTimer = [RHCustomTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(heartTimeCounting) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:self.heartTimer forMode:NSRunLoopCommonModes];
    }
}

-(void)stopHeartTimer
{
    [self.heartTimer invalidate];
    self.heartTimer = nil;
}

-(void)heartTimeCounting
{
    if (self.heartCount == 120) {
        [self sendHeartCmd];
        self.heartCount = 0;
    }else{
        self.heartCount ++;
    }
    NSLog(@"---->蓝牙心跳包计时:%ld",self.heartCount);
}
#pragma mark ------ 发送心跳包指令,随机发一个,保证有通讯就行

-(void)sendHeartCmd
{
    
    NSDictionary *cmd = @{
        @"field":@"Ems_BatSoc",
        @"regAddr":@(206),
        @"bitWidth":@(16),
        @"ratio":@"0.1",
        @"cmdType":@(LocalSettingType_EMS)
    };
    
    RHLocalSettingModel *heartModel = [RHLocalSettingModel yy_modelWithJSON:cmd];
    [[RHBleCmdManager shareMnger] sendHeartCommand:heartModel];
}


@end
